<template>
  <div class="canrocnet-editor">
    <div id="quillToolbar">
      <!-- 字体 -->
      <select class="ql-header">
        <option selected>正文</option>
        <option value="1">标题1</option>
        <option value="2">标题2</option>
        <option value="3">标题3</option>
        <option value="4">标题4</option>
        <option value="5">标题5</option>
        <option value="6">标题6</option>
      </select>
      <!-- 文字大小 -->
      <select class="ql-size">
        <option value="small">小号</option>
        <option selected>标准</option>
        <option value="large">大号</option>
        <option value="huge">超大号</option>
      </select>
      <!-- 加粗 -->
      <button class="ql-bold">加粗</button>
      <!-- 斜体 -->
      <button class="ql-italic">斜体</button>
      <!-- 下划线 -->
      <button class="ql-underline">下划线</button>
      <!-- 中间线 -->
      <button class="ql-strike">中间线</button>
      <!-- 文字颜色 -->
      <select class="ql-color">
        <option selected></option>
        <option value="red">红色</option>
        <option value="green">绿色</option>
        <option value="blue">蓝色</option>
        <option value="orange">橙色</option>
        <option value="purple">紫色</option>
        <option value="black">黑色</option>
      </select>
      <!-- 引用 -->
      <button class="ql-blockquote">引用</button>
      <!-- 代码块 -->
      <button class="ql-code-block">代码块</button>
      <!-- 下标 -->
      <button class="ql-script" value="sub">下标</button>
      <!-- 上标 -->
      <button class="ql-script" value="super">上标</button>
      <!-- 链接 -->
      <button class="ql-link">链接</button>
      <!-- 图片 -->
      <button class="ql-image">图片</button>
      <!-- 视频 -->
      <button class="ql-video">视频</button>
    </div>
    <div id="quillEditor" />
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from "vue";
import Quill from "quill";
import { uploadApi } from "@/api/modules/system/upload";

defineOptions({
  name: "Editor"
});

const props = withDefaults(
  defineProps<{
    modelValue: string;
    height?: string | number;
  }>(),
  {
    modelValue: "",
    height: "400px"
  }
);
const emits = defineEmits<{
  (e: "update:modelValue", value: string): void;
}>();

let quill;
const editorContent = ref(props.modelValue);
const editorHeight = computed(() => {
  return typeof props.height === "number" ? `${props.height}px` : props.height;
});

/**
 * 初始化编辑器
 */
function initQuill() {
  // 初始化编辑器
  quill = new Quill("#quillEditor", {
    modules: {
      toolbar: {
        container: "#quillToolbar",
        handlers: {
          image: handleUploadImage,
          video: handleUploadVideo
        }
      }
    },
    theme: "snow",
    placeholder: "请输入内容"
  });
  // 设置默认值
  quill.root.innerHTML = editorContent.value;
  // 设置编辑器内容变化时的回调
  quill.on("text-change", () => {
    editorContent.value = quill.root.innerHTML;
    emits("update:modelValue", editorContent.value);
  });
}

/**
 * 上传图片
 */
function handleUploadImage() {
  const input = document.createElement("input");
  input.setAttribute("type", "file");
  input.setAttribute("accept", "image/*");
  input.click();

  input.onchange = async () => {
    const file = input.files![0];
    const formData = new FormData();
    formData.append("file", file);

    uploadApi(formData)
      .then(res => {
        if (res.code === 200) {
          const range = quill.getSelection();
          quill.insertEmbed(range.index, "image", `/canrocnet${res.data.url}`);
        } else {
          console.error("上传图片失败");
        }
      })
      .catch(err => {
        console.error("上传图片失败", err);
      });
  };
}

/**
 * 上传视频
 */
function handleUploadVideo() {
  const input = document.createElement("input");
  input.setAttribute("type", "file");
  input.setAttribute("accept", "video/*");
  input.click();

  input.onchange = async () => {
    const file = input.files![0];
    const formData = new FormData();
    formData.append("file", file);

    uploadApi(formData)
      .then(res => {
        if (res.code === 200) {
          const range = quill.getSelection();
          quill.insertEmbed(range.index, "video", `/canrocnet${res.data.url}`);
        } else {
          console.error("上传视频失败");
        }
      })
      .catch(err => {
        console.error("上传视频失败", err);
      });
  };
}

onMounted(() => {
  initQuill();
});
</script>

<style lang="scss" scoped>
.canrocnet-editor {
  --quill-editor-min-height: v-bind(editorHeight);
  :deep(.ql-editor) {
    min-height: var(--quill-editor-min-height);
  }
}
</style>
